/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Nikolaus Vahrenkamp
* @copyright  2013 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/

#ifndef __MMM_MotionFrameEntries_H_
#define __MMM_MotionFrameEntries_H_

#include "../../MMMCore.h"
#include "../../MMMImportExport.h"

#include <Eigen/Core>
#include <string> 
#include <vector>
#include <map>

namespace MMM
{
/*!
	\brief The interface for entires of motion-data.
    Custom motion data entries must derive from this class in order to allow storage within a MotionFrame object.
*/
class MMM_IMPORT_EXPORT MotionFrameEntry
{
public:
    MotionFrameEntry(const std::string &tagName)
    :tagName(tagName)
    {
    }

	//! Must provide an output method to generate XML tags (which are encapsulated in the <motion-data> ... <motion-data> xml definition)
	virtual std::string toXML() = 0;

    //! The XML tag name
    std::string tagName;
};
typedef boost::shared_ptr<MotionFrameEntry> MotionFrameEntryPtr;

/*!
    \brief A standard entry: The root position (3d) of the model given in millimeters.
*/
class MMM_IMPORT_EXPORT RootPosition : public MotionFrameEntry
{
public:
	RootPosition():MotionFrameEntry("RootPosition")
	{
		root_pos.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_pos(0) << " " << root_pos(1) << " " << root_pos(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //! The Cartesian position of the model's root (MM).
	Eigen::Vector3f root_pos;
};
typedef boost::shared_ptr<RootPosition> RootPositionPtr;

/*!
	\brief A standard entry: The velocity of the root position.
*/
class MMM_IMPORT_EXPORT RootPositionVel : public MotionFrameEntry
{
public:
	RootPositionVel() : MotionFrameEntry("RootPositionVelocity")
	{
		root_pos_vel.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_pos_vel(0) << " " << root_pos_vel(1) << " " << root_pos_vel(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //! The velocity of the model's root.
	Eigen::Vector3f root_pos_vel;
};
typedef boost::shared_ptr<RootPositionVel> RootPositionVelPtr;

/*!
	\brief A standard entry: The acceleration of the root position.
*/
class MMM_IMPORT_EXPORT RootPositionAcc : public MotionFrameEntry
{
public:
	RootPositionAcc() : MotionFrameEntry("RootPositionAcceleration")
	{
		root_pos_acc.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_pos_acc(0) << " " << root_pos_acc(1) << " " << root_pos_acc(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //! The acceleration of the model's root.
	Eigen::Vector3f root_pos_acc;
};
typedef boost::shared_ptr<RootPositionAcc> RootPositionAccPtr;


/*!
	\brief A standard entry: The root orientation as RPY angles.
*/
class MMM_IMPORT_EXPORT RootOrientation : public MotionFrameEntry
{
public:
	RootOrientation() : MotionFrameEntry("RootRotation")
	{
		root_ori.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_ori(0) << " " << root_ori(1) << " " << root_ori(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //! The orientation of the model's root.
	Eigen::Vector3f root_ori;
};
typedef boost::shared_ptr<RootOrientation> RootOrientationPtr;

/*!
	\brief A standard entry: The velocity of the root orientation.
*/
class MMM_IMPORT_EXPORT RootOrientationVel : public MotionFrameEntry
{
public:
	RootOrientationVel() : MotionFrameEntry("RootRotationVelocity")
	{
		root_ori_vel.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_ori_vel(0) << " " << root_ori_vel(1) << " " << root_ori_vel(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //! The orientation velocity of the model's root.
	Eigen::Vector3f root_ori_vel;
};
typedef boost::shared_ptr<RootOrientationVel> RootOrientationVelPtr;

/*!
	\brief A standard entry: The acceleration of the root Orientation.
*/
class MMM_IMPORT_EXPORT RootOrientationAcc : public MotionFrameEntry
{
public:
	RootOrientationAcc() : MotionFrameEntry("RootRotationAcceleration")
	{
		root_ori_acc.setZero();
	}

	//! Generate XML tag
	virtual std::string toXML()
	{
		std::string tab = "\t\t\t\t";
		std::stringstream res;
		res << tab << "<" << tagName << ">" << root_ori_acc(0) << " " << root_ori_acc(1) << " " << root_ori_acc(2) << "</" << tagName << ">" << endl;
		return res.str();
	}

    //!The acceleration of the root Orientation.
	Eigen::Vector3f root_ori_acc;
};
typedef boost::shared_ptr<RootOrientationAcc> RootOrientationAccPtr;

}

#endif 
